#!/bin/sh
# PCP QA Test No. 1222
# Exercise multiple DSO PMDAs using pmdaDynamic APIs.
#
# Copyright (c) 2017 Red Hat.
#

seq=`basename $0`
echo "QA output created by $seq"

# get standard environment, filters and checks
. ./common.product
. ./common.filter
. ./common.check

_check_valgrind

[ $PCP_PLATFORM = linux ] || _notrun "Linux-specific PMDAs used in test case"

_cleanup()
{
    cd $here
    $sudo rm -rf $tmp $tmp.*
}

status=1	# failure is the default!
trap "_cleanup; exit \$status" 0 1 2 3 15

# assorted metrics may not be there, plus these rippers ...
# [Mon Dec 18 20:31:35] pminfo(8372) Error: pmdaFetch: Fetch callback error from metric PMID 3.11.0[1]: No data available
# [Tue Sep  2 16:54:58] pminfo(3502278) Error: pmdaFetch: Fetch callback error from metric PMID 3.9.7[833]: No such process
# which come from kernel threads that don't have expected values
# for the metrics proc.psinfo.cgroups (PMID: 3.11.0) and
# proc.memory.maps (PMID: 3.9.7)
#
# and ERROR SUMMARY may appear twice because some valgrind versions
# get confused and report summary stats for 2 threads ... take the
# first one only (and punt)
#
# and may be some babble about process accounting ...
# [Fri Nov 24 06:25:25] pminfo(562948) Warning: acct: existing pacct file did not grow as expected, file system full?
# [Fri Nov 24 06:25:25] pminfo(562948) Info: acct: enable -Dappl3 for more detailed logging
#
_filter()
{
    tee -a $seq_full \
    | sed \
	-e "s,$PCP_PMDAS_DIR,PCP_PMDAS_DIR,g" \
	-e '/^proc\.autogroup\.id: No value(s) available/d' \
	-e '/^proc\.autogroup\.nice: No value(s) available/d' \
	-e '/^proc\.id\.container: No data available/d' \
	-e '/^proc\.namespaces\.envid: No value(s) available/d' \
	-e '/^proc\.schedstat\.envid: Metric not supported/d' \
	-e '/^proc\.schedstat\.pcount: Metric not supported/d' \
	-e '/^proc\.schedstat\..*: No value(s) available/d' \
	-e '/^proc\.namespaces\..*: Metric not supported/d' \
	-e '/^proc\.smaps\..*: Metric not supported/d' \
	-e '/^proc\.smaps\..*: No value(s) available/d' \
	-e '/^proc\.psinfo\.cgroups: No data available/d' \
	-e '/^proc\.psinfo\.cgroups: No value(s) available/d' \
	-e '/^proc\.id\.container: Missing metric value(s)/d' \
	-e '/^proc\.psinfo\.labels: No value(s) available/d' \
	-e '/^proc\.psinfo\.ngid: Metric not supported by this version/d' \
	-e '/^proc\.fdinfo\..*: Metric not supported/d' \
	-e '/^proc\.fdinfo\..*: No value(s) available/d' \
	-e '/pmdaFetch: Fetch callback error from metric PMID 3\.11\.0\[.*]: No data available/d' \
	-e '/pmdaFetch: Fetch callback error from metric PMID 3\.9\.7\[.*]: No such process/d' \
	-e '/proc\.psinfo\.tty_pgrp: No value(s) available/d' \
	-e '/ acct: existing pacct file did not grow /d' \
	-e '/ acct: enable -Dappl3 /d' \
	-e '/^Command: /s/,proc_init .*/,proc_init ... metrics .../' \
	-e '/ERROR SUMMARY/q' \
    # end
}

# for pminfo -f ... don't care so much about details of values (-v
# checks for errors), rather want to exercise code paths for valgrind
# sed at the end is required to cull some metrics that sometimes have
# no values
#
# we do need to cull any metrics that might not be supported on some
# platforms
#
# seen note above re:  ERROR SUMMARY
#
_filter_f()
{
    $PCP_AWK_PROG '
BEGIN				{ skip = 1 }
$1 == "==="			{ print
			  	  if ($0 ~ /valgrind report/) skip = 0
				  next
				}
skip == 0			{ print; next }
/^proc\.runq/			{ print $1 ": some values"; next }
/^proc\./			{ seen = 1; numval = 0; metric = $1; next }
$1 == "inst" || $1 == "value"	{ numval++; next }
NF == 0 && seen == 1		{ if (numval == 1) print metric ": 1 value"
				  else if (numval <= 10) print metric ": " numval " values"
				  else print metric ": >10 values"
				  seen = 0
				}' \
    | sed \
	-e "s,$PCP_PMDAS_DIR,PCP_PMDAS_DIR,g" \
	-e '/^proc\.autogroup\.id:/d' \
	-e '/^proc\.autogroup\.nice:/d' \
	-e '/^proc\.id\.container:/d' \
	-e '/^proc\.namespaces\./d' \
	-e '/^proc\.psinfo\.cgroups:/d' \
	-e '/^proc\.psinfo\.labels:/d' \
	-e '/^proc\.psinfo\.ngid:/d' \
	-e '/^proc\.psinfo\.tty_pgrp:/d' \
	-e '/^proc\.smaps\./d' \
	-e '/^proc\.fdinfo\./d' \
	-e '/^Command: /s/,proc_init .*/,proc_init ... metrics .../' \
	-e '/ERROR SUMMARY/q' \
    # end
}

# real QA test starts here
linux_pmda=$PCP_PMDAS_DIR/linux/pmda_linux,linux_init
proc_pmda=$PCP_PMDAS_DIR/proc/pmda_proc,proc_init

# bypass access controls, so proc indom is expanded and used
#
export PROC_ACCESS=1

# order of proc metrics is non-deterministic ... take control
#
pminfo -L -Kclear -Kadd,60,$linux_pmda -Kadd,3,$proc_pmda proc 2>>$seq_full \
| LC_COLLATE=POSIX sort >$tmp.metrics
echo "=== metrics ===" >>$seq_full
cat $tmp.metrics >>$seq_full
echo "=== end metrics ===" >>$seq_full

echo "=== check for errors, silence is golden ==="
_run_valgrind --sudo pminfo -vL -Kclear -Kadd,60,$linux_pmda -Kadd,3,$proc_pmda `cat $tmp.metrics` 2>&1 \
| _filter

echo
echo "=== check number of values ==="
( _run_valgrind --sudo pminfo -fL -Kclear -Kadd,60,$linux_pmda -Kadd,3,$proc_pmda `cat $tmp.metrics` 2>&1 \
  ; echo ) \
| _filter_f

# success, all done
status=0
exit
